﻿using System;
using System.ComponentModel;
using System.IO;
using System.Xml.Serialization;
using SVNClean.Properties;
using System.Drawing.Design;
using System.Drawing;

namespace SVNClean.Modules {
    [Serializable]
    public class AppConfiguration {
        /// <summary>
        /// Initializes a new instance of the <see cref="AppConfiguration"/> class.
        /// </summary>
        public AppConfiguration() {

        }

        /// <summary>
        /// Gets the config file path.
        /// </summary>
        /// <value>The config file path.</value>
        [XmlIgnore, Browsable(false)]
        private static string ConfigFilePath {
            get { return Environment.CurrentDirectory + Resources.ConfigPath; }
        }

        #region "[rgn] Public Properties "
        [XmlElement, DisplayName("Show Files")]
        [Category("Explorer")]
        [Description("Indicates whether the explorer window can show files in Explorer Window.")]
        public bool ShowFiles { get; set; }

        [XmlElement, DisplayName("Show Hidden Files")]
        [Category("Explorer")]
        [Description("Indicates whether the explorer window can show hidden files in Explorer Window.")]
        public bool ShowHiddenFiles { get; set; }

        [XmlElement, DisplayName("Show Hidden Folders")]
        [Category("Explorer")]
        [Description("Indicates whether the explorer window can show hidden folders in Explorer Window.")]
        public bool ShowHiddenFolders { get; set; }

        [XmlElement, DisplayName("Create Backup")]
        [Category("Clean Proccess")]
        [Description("Indicates whether the system should backup before clean a directory.")]
        public bool CreateBackup { get; set; }

        [XmlElement, DisplayName("Delete Backup's")]
        [Category("Clean Proccess")]
        [Description("Indicates whether the system should delete old backup's before create a new one.")]
        public bool DeleteOldBackup { get; set; }

        [XmlElement, DisplayName("Close on Finish")]
        [Category("Clean Proccess")]
        [Description("Indicates whether the system should close 'Clean Process Window' after finish all actions.")]
        public bool CloseAfterFinish { get; set; }

        [XmlElement, DisplayName("Save Log")]
        [Category("Log")]
        [Description("Indicates whether the system should save a detailed log after clean directories.")]
        public bool SaveOperationLog { get; set; }

        [XmlElement, DisplayName("Open Log")]
        [Category("Log")]
        [Description("Indicates whether the system should open the created log after finish clean actions.")]
        public bool OpenLogAfterClean { get; set; }

        [XmlElement, Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public string svnPathForeColor { get; set; }

        [XmlIgnore, DisplayName("SVN Path ForeColor")]
        [Category("Appearance")]
        [Description("Gets or sets the color of the SVN path.")]
        public Color SVNPathForeColor {
            get {
                if (!string.IsNullOrEmpty(svnPathForeColor))
                    return System.Drawing.ColorTranslator.FromHtml(svnPathForeColor);
                return System.Drawing.Color.Empty;
            }
            set { svnPathForeColor = System.Drawing.ColorTranslator.ToHtml(value); }
        }

        [XmlElement, Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public string svnPathBackColor { get; set; }

        [XmlIgnore, DisplayName("SVN Path BackColor")]
        [Category("Appearance")]
        [Description("Gets or sets the back color of the SVN path.")]
        public Color SVNPathBackColor {
            get {
                if (!string.IsNullOrEmpty(svnPathBackColor))
                    return System.Drawing.ColorTranslator.FromHtml(svnPathBackColor);
                return System.Drawing.Color.Empty;
            }
            set { svnPathBackColor = System.Drawing.ColorTranslator.ToHtml(value); }
        }

        private string defaultSkin;
        [XmlElement, DisplayName("Skin")]
        [Category("Appearance")]
        [Description("Indicates the application default skin theme. Full list is available for exchange.")]
        [TypeConverter(typeof(SkinTypeConverter))]
        public string DefaultSkin {
            get {
                return defaultSkin;
            }
            set {
                defaultSkin = value;
                if (SkinChanged != null) SkinChanged(this, EventArgs.Empty);
            }
        }

        [XmlElement, DisplayName("Last Directory")]
        [Category("History")]
        [Description("The last cleaned directory.")]
        public string LastCleanedDirectory { get; set; }

        [XmlElement, DisplayName("Save Last Directory")]
        [Category("History")]
        [Description("Indicates whether the system should save the last cleaned directory.")]
        public bool SaveLastDirectory { get; set; }

        [Browsable(false)]
        public event EventHandler SkinChanged;
        #endregion

        private static AppConfiguration current;
        /// <summary>
        /// Gets the current.
        /// </summary>
        /// <value>The current.</value>
        [XmlIgnore, Browsable(false)]
        public static AppConfiguration Current {
            get {
                if (current == null) {
                    current = new AppConfiguration();
                    current.LoadData();
                }
                return current;
            }
        }

        /// <summary>
        /// Loads the data.
        /// </summary>
        /// <returns></returns>
        public AppConfiguration LoadData() {
            if (File.Exists(ConfigFilePath)) {
                var sr = new StreamReader(ConfigFilePath);
                try {
                    var xml = sr.ReadToEnd();
                    var app = (AppConfiguration)xml.Deserialize(typeof(AppConfiguration));
                    this.CloseAfterFinish = app.CloseAfterFinish;
                    this.CreateBackup = app.CreateBackup;
                    this.DeleteOldBackup = app.DeleteOldBackup;
                    this.ShowFiles = app.ShowFiles;
                    this.ShowHiddenFiles = app.ShowHiddenFiles;
                    this.ShowHiddenFolders = app.ShowHiddenFolders;
                    this.SaveOperationLog = app.SaveOperationLog;
                    this.OpenLogAfterClean = app.OpenLogAfterClean;
                    this.DefaultSkin = app.DefaultSkin;
                    this.LastCleanedDirectory = app.LastCleanedDirectory;
                    this.SaveLastDirectory = app.SaveLastDirectory;
                    this.svnPathBackColor = app.svnPathBackColor;
                    this.svnPathForeColor = app.svnPathForeColor;
                    current = this;
                    return current;
                }
                finally { sr.Close(); }
            }
            else {
                current = new AppConfiguration();
                current.SaveOperationLog = true;
                current.DefaultSkin = "Blue";
                current.CreateBackup = true;
                current.SaveLastDirectory = true;
                current.svnPathForeColor = System.Drawing.ColorTranslator.ToHtml(System.Drawing.Color.Firebrick);
                current.svnPathBackColor = System.Drawing.ColorTranslator.ToHtml(System.Drawing.Color.MistyRose);
                current.LastCleanedDirectory = Directory.GetLogicalDrives()[0];
                SaveData(current);
                return current;
            }
        }

        /// <summary>
        /// Saves the data.
        /// </summary>
        public void SaveData() {
            SaveData(this);
        }

        /// <summary>
        /// Resets to default.
        /// </summary>
        public void ResetToDefault() {
            if (File.Exists(ConfigFilePath)) File.Delete(ConfigFilePath);
            LoadData();
        }

        /// <summary>
        /// Saves the data.
        /// </summary>
        /// <param name="obj">The obj.</param>
        public void SaveData(AppConfiguration obj) {
            if (File.Exists(ConfigFilePath)) File.Delete(ConfigFilePath);
            if (!Directory.Exists(Environment.CurrentDirectory + Resources.ConfigDirectory)) {
                Directory.CreateDirectory(Environment.CurrentDirectory + Resources.ConfigDirectory);
            }
            string xml = obj.Serialize();
            var sw = new StreamWriter(ConfigFilePath);
            try {
                sw.Write(xml);
                sw.Flush();
            }
            finally { sw.Close(); }
        }

    }
}
